/*
 * Copyright 2017 Matthew Tamlin
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.matthewtamlin.fortytwo.library_tests;

import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ComponentState;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.window.service.WindowManager;

import com.matthewtamlin.fortytwo.library.answer.PojoAnswer;
import com.matthewtamlin.fortytwo.library.answer_view.SimpleAnswerCard;

/**
 * A test harness for the {@link SimpleAnswerCard} class. This class is abstract because the test
 * view is abstract.
 */
public abstract class SimpleAnswerCardTestHarness
    extends ControlsBelowViewTestHarness<SimpleAnswerCard> {
    private static final int ANIMATION_DURATION_INCREMENT_MS = 50;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.getIntColor("#666666"));

        getControlsContainer().addComponent(createIncreaseAnimationDurationButton());
        getControlsContainer().addComponent(createDecreaseAnimationDurationButton());
        getControlsContainer().addComponent(createMarkButton());
        getControlsContainer().addComponent(createUnmarkButton());
        getControlsContainer().addComponent(createSelectButton());
        getControlsContainer().addComponent(createDeselectButton());
        getControlsContainer().addComponent(createMarkAndSelectButton());
        getControlsContainer().addComponent(createUnmarkAndDeselectButton());
        getControlsContainer().addComponent(createSetAnswerCorrectButton());
        getControlsContainer().addComponent(createSetAnswerIncorrectButton());
        getControlsContainer().addComponent(createSetIdentifierButton());
    }

    /**
     * Creates a button which increasing the test view animation duration when clicked.
     *
     * @return the button, not null
     */
    private Button createIncreaseAnimationDurationButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Increase animation duration");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                final int newDuration = getTestView().getAnimationDurationMs()
                    + ANIMATION_DURATION_INCREMENT_MS;
                getTestView().setAnimationDurationMs(newDuration);
            }
        });

        return b;
    }

    /**
     * Creates a button which decreases the test view animation duration when clicked.
     *
     * @return the button, not null
     */
    private Button createDecreaseAnimationDurationButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Decrease animation duration");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                final int newDuration = getTestView().getAnimationDurationMs()
                    - ANIMATION_DURATION_INCREMENT_MS;
                getTestView().setAnimationDurationMs(newDuration < 0 ? 0 : newDuration);
            }
        });

        return b;
    }

    /**
     * Creates a button which marks the test view when clicked.
     *
     * @return the button, not null
     */
    private Button createMarkButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Mark");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getTestView().setMarkedStatus(true, true);
            }
        });

        return b;
    }

    /**
     * Creates a button which unmarks the test view when clicked.
     *
     * @return the button, not null
     */
    private Button createUnmarkButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Unmark");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getTestView().setMarkedStatus(false, true);
            }
        });

        return b;
    }

    /**
     * Creates a button which selects the test view when clicked.
     *
     * @return the button, not null
     */
    private Button createSelectButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Select");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getTestView().setSelectedStatus(true, true);
            }
        });

        return b;
    }

    /**
     * Creates a button which deselects the test view when clicked.
     *
     * @return the button, not null
     */
    private Button createDeselectButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Deselect");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getTestView().setSelectedStatus(false, true);
            }
        });

        return b;
    }

    /**
     * Creates a button which both marks and selects the test view when clicked.
     *
     * @return the button, not null
     */
    private Button createMarkAndSelectButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Mark and select");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getTestView().setStatus(true, true, true);
            }
        });

        return b;
    }

    /**
     * Creates a button which both unmarks and deselects the test view when clicked.
     *
     * @return the button, not null
     */
    private Button createUnmarkAndDeselectButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Unmark and deselect");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getTestView().setStatus(false, false, true);
            }
        });

        return b;
    }

    /**
     * Creates a button which sets a correct answer in the text view when clicked.
     *
     * @return the button, not null
     */
    private Button createSetAnswerCorrectButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Set answer (correct) button");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getTestView().setAnswer(new PojoAnswer("answer (correct)", true), true);
            }
        });

        return b;
    }

    /**
     * Creates a button which sets an incorrect answer in the text view when clicked.
     *
     * @return the button, not null
     */
    private Button createSetAnswerIncorrectButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Set answer (incorrect) button");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getTestView().setAnswer(new PojoAnswer("answer (incorrect)", false), true);
            }
        });

        return b;
    }

    /**
     * Creates a button which sets the identifier in the text view when clicked.
     *
     * @return the button, not null
     */
    private Button createSetIdentifierButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Set identifier");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getTestView().setIdentifier("A", true);
            }
        });

        return b;
    }

    private void configBtn(Button b) {
        final int padding = 20;
        final int paddingTop = 25;
        final int textSize = 40;
        b.setPadding(padding, paddingTop, padding, paddingTop);
        b.setTextSize(textSize);
        b.setTextColor(new Color(Color.getIntColor("#333333")));

        StateElement stateElement = new StateElement();
        ShapeElement selectedElement = new ShapeElement(getContext(), ResourceTable.Graphic_btn_bg_press);
        ShapeElement emptyElement = new ShapeElement(getContext(), ResourceTable.Graphic_btn_bg_normal);
        stateElement.addState(new int[]{ComponentState.COMPONENT_STATE_PRESSED}, selectedElement);
        stateElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, emptyElement);
        b.setBackground(stateElement);

        b.setLayoutConfig(new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,
            ComponentContainer.LayoutConfig.MATCH_CONTENT));

        final int margin = 10;
        b.setMarginRight(margin);
        b.setMarginBottom(margin);
        b.setMarginLeft(margin);
        b.setMarginTop(margin);

        b.setFont(Font.DEFAULT_BOLD);
    }
}